<?php
/*
 * kernel/object.i18n.php
 *
 * This code is distributed and used under the GNU GPL v2 License,
 * please, read file LICENSE, which is situated in root directory,
 * or in "LICENSE" directory with most acceptable translation for you
 * 
 * Languages and internationalization
 *
 * Copyright (C) 2010, Taras Kudla
 *
 */


/**
 * 
 */
class gi18n_image{
	private $data=array();
	public function get($key){
		return ( !isset($this->data[$key]) || is_null($this->data[$key]))?false:$this->data[$key];
	}
	public function set($array,&$caller){
		if(get_class($caller)!="gI18n")return false;
		$this->data=$array;
		return true;
	}
}

/**
 * 
 */
class gI18n extends gKernel{
	private $SysLang= array();
	public $cache   = array();
	
	private $pattern1 = "/ *([A-z0-9_-]{1,20}) *\| *([^\r\n]+) */"; # key | value
	private $pattern2 = "/>>> *([A-z0-9_-]{1,20}) *>>> *(.+) *<<</Us"; # >>> key >>> value <<< (for multiple strings)

	/**
         * Parses string or text file data to comaptible key-value array
         *
         * @param string $data  string to compatible object
         * @return array
         */
	private function parsedata($data){
		$tmp=array();
		$tmp2=array();
		$a=preg_match_all($this->pattern1,$data,$tmp);
		$b=preg_match_all($this->pattern2,$data,$tmp2);
		if( !$a && !$b){
			return false;
		} else {
			$_1=(isset($tmp[1]) && count($tmp[1])>0  )?array_combine(array_values($tmp[1]),array_values($tmp[2])):array();
            		$_2=(isset($tmp2[1]) && count($tmp2[1])>0  )?array_combine(array_values($tmp2[1]),array_values($tmp2[2])):array();
			return array_merge($_1,$_2);
		}
	}
	/**
         * Returns language value by key
         *
         * @param string $key key name
         * @return string
         */
	public function get($key){
            if(!is_object($this->SysLang)){
                $file = $this->core->corepath()."i18n/".$this->core->language();
                $image=$this->parsefile($file);
                if( !is_object($image) ){
                    return false;
                }
                $this->SysLang=&$image;
                }
            return $this->SysLang->get($key);
        }
	/**
         * Returns parsed text as an compatible i18n language object
         *
         * @param string $text
         * @return gi18n_image 
         */
	public function parse($text=null){
            if( $text == null){
                $text = "k1 | v1";
            }
            $array = $this->parsedata($text);
            if( !$array ) {
                return false;
            } else {
                $image = new gi18n_image();
                $image->set($array,$this);
                return $image;
            }
        }
	# parsing from file and caching implementation
	public function & parsefile($file){
		$false=false;
		# checking if file exists
		if( !file_exists($file)){
			return $false;
		}
		$filehash = md5($file);
		# caching system
		if( $this->core->get("usecache") &&  $this->core->isloaded("cache")){
			$name = "gepard.lang.".$filehash;
			$datename = $name.".date";
			$ctime = $this->core->cache->get($datename);
			if( $ctime ){
				$mtime = filemtime($file);
				if( $mtime > $ctime){
					#need to rebuild cache
					$filedata=$this->getlangfiledata($file);
                                        /*
                                         * checking for file encoding
                                         */
					$langarray = $this->parsedata($filedata);
					if( is_bool($langarray) && !$langarray){
						return $false;
					}
					$this->core->cache->set($datename,time());
					$this->core->cache->set($name,serialize($langarray));
					$this->core->debug("lang","rebuilding cache for langdata: '$file' ");
				}else {
					#returning data from cache
					$filedata = $this->core->cache->get($name);
					$langarray = unserialize($filedata);
					$this->core->debug("lang","getting langdata from cache");
				}
			} else {
				# need to build cache
				$filedata=$this->getlangfiledata($file);
				$langarray = $this->parsedata($filedata);
				if( is_bool($langarray) && !$langarray){
					return $false;
				}
				$this->core->cache->set($datename,time());
				$this->core->cache->set($name,serialize($langarray));
				$this->core->debug("view","putting template data into cache");
			}
		} else {
			# when caching is disabled
			$filedata=$this->getlangfiledata($file);
			$langarray = $this->parsedata($filedata);
			if( is_bool($langarray) && !$langarray){
				return $false;
			}
		}
		$langimage = new gi18n_image();
		$langimage->set($langarray,$this);
		return $langimage;
	}

	# setting module language
	public function setModuleLanguage($module,$itlanguages,$default,$path=null){
		if(in_array($this->core->language(),$itlanguages)){
			$l=$this->core->language();
		}else{
			$l=$default;
		}
		if( array_key_exists($module,$this->cache) && is_object($this->cache[$module])){
			return $this->cache[$module];
		}
		if( $path==null){
			if( $this->core->cms->checkappmod($module) ){
			    $path=$this->core->parseasdir($this->core->get("appmodsdir")).$module."/lang/";
			} else {
			    $path=$this->core->parseasdir($this->core->get("modsdir")).$module."/lang/";
			}
		} else {
			$path = $this->core->parsepathtosys($path);
		}
		$file=$path.$l;
		$image = $this->parsefile($file);
		if( is_bool($image) && !$image) {
			$image = new gi18n_image();
		}
		$this->core->debug("LANG","Trying to parse lang file $file");
		$this->cache[$module]=$image;
		return $this->cache[$module];
	}
	# get mod lang key
	public function getmodlangbykey($module,$key){
		if( array_key_exists($module,$this->cache) && is_object($this->cache[$module])){
			return $this->cache[$module]->get($key);
		} else return null;
	}
	# getting module language object
	public function getlangobj($mod){
		if( array_key_exists($mod,$this->cache) && is_object($this->cache[$mod])){
			return $this->cache[$mod];
		} else return null;
	}

        /*
         * Get language text file
         * NOTE: Please, use this function for full
         *       support of charsets etc.
         */
         public function getlangfiledata($filename,$path=null){
             if( $path==null){
                 $path = dirname($filename)."/";
                 $filename  = basename($filename);                 
             }
             # 
             $directfile = $path.$filename;
             $charsfile  = $path.$this->core->charset->getcnname(_CHARSET_CNLANGFILE).".".$filename;
             if(file_exists($charsfile)){
                 $this->core->debug("lang","Loaded file with native encoding: $charsfile");
                 return file_get_contents($charsfile);
             }
             if(file_exists($directfile)){
                 $this->core->debug("lang","Loaded file: $directfile");
                 return $this->core->charset->gettextfile($directfile);
             }
             return false;
        }

}